using System;
using System.Collections.Generic;
using Main.Details;
using Main.Event;
using Main.Inventory;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using ZSW.Framework;
using ZSW.Framework.UIElement;

namespace Main.UI
{
    public class UI_InventorySystem : ZSWF_BaseUIElement
    {
        [SerializeField] private UI_ToolTip_Item toolTip;

        [Header("拖拽图片")]
        [SerializeField] private Image dragImage;


        [Header("玩家背包UI")]
        [SerializeField] private Button openBagButton;
        [SerializeField] private TMP_Text MoneyText;
        [SerializeField] private ZSWF_BaseUIElement PlayerBag;
        [SerializeField] private UI_Slot_Bag[] slots;
        [SerializeField] private bool bagOpened;

        [Header("通用背包")]
        [SerializeField] private UI_Player_Bag baseBag;
        public UI_Slot_Bag shopSlotPrefab;
        [SerializeField] private List<UI_Slot_Bag> baseBagSlots;

        [Header("储物箱")]
        public UI_Slot_Bag boxSlotPrefab;

        [Header("交易面板")]
        [SerializeField] private UI_Trade Trade;

        private Dictionary<InventoryLocation, Action<List<InventoryItem>>> callbackDic;

        public override void Init()
        {
            base.Init();

            for (int i = 0; i < slots.Length; i++)
            {
                int index = i;
                slots[index].slotIndex = index;
                slots[index].SetInventoryUI(this);
            }

            callbackDic = new Dictionary<InventoryLocation, Action<List<InventoryItem>>>()
            {
                {InventoryLocation.Player, OnUpdatePlayerBag},
                {InventoryLocation.Box, OnUpdateBox}
            };

            MainEventSystem.UpdateInventoryUI += OnUpdateInventoryUI;
            MainEventSystem.BeforeLoadSceneEvent += OnBeforeLoadScene;
            MainEventSystem.BaseBagOpenEvent += OnBaseBagOpen;
            MainEventSystem.BaseBagCloseEvent += OnBaseBagClose;
            MainEventSystem.ShowTradeUIEvent += OnShowTradeUI;


            openBagButton.onClick.AddListener(() => PlayerBag.SwitchState(!PlayerBag.gameObject.activeInHierarchy));
        }

        private void OnShowTradeUI(ItemDetails details, bool isSell)
        {
            Trade.SetupTradeUI(details, isSell);
            Trade.Show();
        }

        private void OnBaseBagClose(SlotType slotType, InventoryBag_SO bagData)
        {
            toolTip.gameObject.SetActive(false);
            OnSlotClick(-1);
            foreach (var slot in baseBagSlots)
            {
                Destroy(slot.gameObject);
            }

            if (slotType == SlotType.Shop)
            {
                PlayerBag.Hide();
                bagOpened = false;
            }

            baseBagSlots.Clear();
            baseBag.Hide();
        }

        private void OnBaseBagOpen(SlotType slotType, InventoryBag_SO bagData)
        {
            UI_Slot_Bag prefab = slotType switch
            {
                SlotType.Shop => shopSlotPrefab,
                SlotType.Box => boxSlotPrefab,
                _ => null,
            };

            baseBag.Show();

            baseBagSlots = new();

            for (int i = 0; i < bagData.InventoryList.Count; i++)
            {
                var slot = Instantiate(prefab, baseBag.slotParent);
                slot.slotIndex = i;
                slot.SetInventoryUI(this);

                baseBagSlots.Add(slot);
            }

            // 同时显示玩家背包和商品/箱子背包
            if (slotType == SlotType.Shop || slotType == SlotType.Box)
            {
                PlayerBag.Show();
                bagOpened = true;
            }

            // 更新ui显示
            OnUpdateInventoryUI(InventoryLocation.Box, bagData.InventoryList);
        }

        private void OnBeforeLoadScene()
        {
            OnSlotClick(-1);
        }

        private void Update()
        {
            if (Input.GetKeyDown(KeyCode.B))
            {
                PlayerBag.SwitchState(!PlayerBag.gameObject.activeInHierarchy);
            }
        }

        private void OnDestroy()
        {
            MainEventSystem.UpdateInventoryUI -= OnUpdateInventoryUI;
        }

        private void OnUpdateInventoryUI(InventoryLocation location, List<InventoryItem> list)
        {
            if (callbackDic.TryGetValue(location, out var callback))
            {
                callback?.Invoke(list);
            }
        }

        private void OnUpdatePlayerBag(List<InventoryItem> list)
        {
            InventoryManager inventory = ZSWF_IOCContainer.Get<InventoryManager>();
            for (int i = 0; i < slots.Length; i++)
            {
                if (list[i].ItemAmount > 0)
                {
                    if (inventory.TryGetItemDetails(list[i].ItemID, out var itemDetails))
                    {
                        slots[i].SetItemData(itemDetails, list[i].ItemAmount);
                    }
                }
                else if (slots[i].CurrentItemDetails != null)
                {
                    slots[i].ClearSlot();
                }
            }
            MoneyText.text = inventory.playerMoney.ToString();
        }

        private void OnUpdateBox(List<InventoryItem> list)
        {
            InventoryManager inventory = ZSWF_IOCContainer.Get<InventoryManager>();
            for (int i = 0; i < baseBagSlots.Count; i++)
            {
                if (list[i].ItemAmount > 0)
                {
                    if (inventory.TryGetItemDetails(list[i].ItemID, out var itemDetails))
                    {
                        baseBagSlots[i].SetItemData(itemDetails, list[i].ItemAmount);
                    }
                }
                else if (baseBagSlots[i].CurrentItemDetails != null)
                {
                    baseBagSlots[i].ClearSlot();
                }
            }
        }

        /// <summary>
        /// 指定索引位置UI高亮显示, 输入-1取消所有的高亮效果
        /// </summary>
        /// <param name="slotIndex"></param>
        public void OnSlotClick(int slotIndex)
        {
            // Debug.Log(slotIndex);
            for (int i = 0; i < slots.Length; i++)
            {
                int index = i;
                if (index == slotIndex)
                {
                    slots[slotIndex].SwitchHighLight();
                }
                else
                {
                    slots[index].DisableHighLight();
                }
            }
        }

        public void OnSlotBeginDrag(Sprite sprite)
        {
            dragImage.enabled = true;
            dragImage.sprite = sprite;
            dragImage.SetNativeSize();
        }

        public void OnSlotDrag(Vector3 position)
        {
            dragImage.transform.position = position;
        }

        public void OnSlotEndDrag(SlotType slotType, int slotIndex, RaycastResult raycastResult)
        {
            UI_Slot_Bag currentSlot = null;
            switch (slotType)
            {
                case SlotType.Bag:
                    currentSlot = slots[slotIndex];
                    break;
                case SlotType.Shop:
                    currentSlot = baseBagSlots[slotIndex];
                    break;
            }

            dragImage.enabled = false;

            if (raycastResult.gameObject != null)
            {
                if (raycastResult.gameObject.TryGetComponent(out UI_Slot_Bag targetSlot))
                {

                    if (currentSlot.slotType == SlotType.Bag && targetSlot.slotType == SlotType.Bag)
                    {
                        ZSWF_IOCContainer.Get<InventoryManager>().SwapItem(SlotType.Bag, slotIndex, targetSlot.slotIndex);
                    }
                    // 买商品
                    else if (currentSlot.slotType == SlotType.Shop && targetSlot.slotType == SlotType.Bag)
                    {
                        MainEventSystem.CallShowTradeUI(currentSlot.CurrentItemDetails, false);
                    }
                    // 卖商品
                    else if (currentSlot.slotType == SlotType.Bag && targetSlot.slotType == SlotType.Shop)
                    {
                        MainEventSystem.CallShowTradeUI(currentSlot.CurrentItemDetails, true);
                    }
                    // 存物品
                    else if (currentSlot.slotType == SlotType.Bag && targetSlot.slotType == SlotType.Box)
                    {

                        ZSWF_IOCContainer.Get<InventoryManager>().SwapItem(InventoryLocation.Player, InventoryLocation.Box, slotIndex, targetSlot.slotIndex);
                    }
                    // 取物品
                    else if (currentSlot.slotType == SlotType.Box && targetSlot.slotType == SlotType.Bag)
                    {
                        ZSWF_IOCContainer.Get<InventoryManager>().SwapItem(InventoryLocation.Box, InventoryLocation.Player, slotIndex, targetSlot.slotIndex);
                    }
                }
            }
            // 丢弃背包中的物品
            else if (slotType == SlotType.Bag)
            {
                ItemDetails itemDetails = currentSlot.CurrentItemDetails;

                if (itemDetails.CanDropped)
                {
                    Vector3 pos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, -Camera.main.transform.position.z));
                    // ZSWF_IOCContainer.Get<ItemManager>().CreateItem(itemDetails.ItemID, pos);
                    ZSWF_IOCContainer.Get<InventoryManager>().TryAddItemToBag(itemDetails.ItemID, -1);
                }

            }
        }

        private InventoryLocation SlotTypeToLocation(SlotType slotType)
        {
            switch (slotType)
            {
                case SlotType.Bag:
                    return InventoryLocation.Player;
                case SlotType.Box:
                    return InventoryLocation.Box;
            }
            return InventoryLocation.Player;
        }

        internal void ShowToolTip(ItemDetails currentItemDetails, SlotType slotType, Vector2 position)
        {
            toolTip.SwitchState(true);
            toolTip.SetupToolTip(currentItemDetails, slotType, position);
            toolTip.SetResourceItem(currentItemDetails.ItemID);
        }

        public void HideToolTip()
        {
            toolTip.SwitchState(false);
        }
    }
}

